package com.navi.heartbeat.repository;

import org.springframework.data.domain.Example;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.Repository;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import java.io.Serializable;
import java.util.List;

@NoRepositoryBean
@org.springframework.stereotype.Repository
public interface NaviRepository<T, ID extends Serializable>
        extends Repository<T, ID> {

    T get(ID id);

    /**
     * 需要加锁的地方，必须在方法前声明事务注解@Transactional ,否则锁将不会成功
     * PS: 之前ICIM版本的库之所以不用@Transactional，是因为在AOP中开启了事务。
     * 这样做的坏处是，有些查询的业务是不需要事务的，全部开启反而降低了系统的效能
     *
     * @param id
     * @return
     */
    T getWithLock(ID id);

    Query createQuery(String qlString);

    Query createNativeQuery(String sqlString);

    long count(String countSql);

    List<T> find(String hql);

    List<T> findBySql(String sql);

    List findBySQL(String sql);

    List<T> list(String hql, Object... params);

    /**
     * 需要加锁的地方，必须在方法前声明事务注解@Transactional ,否则锁将不会成功
     * PS: 之前icim版本的库之所以不用，是因为在AOP中开启了事务。
     * 这样做的坏处时，有些查询的业务是不需要事务的，全部开启反而降低了系统的效能
     *
     * @param hql
     * @param params
     * @return
     */
    List<T> listWithLock(String hql, Object... params);

    <S extends T> boolean exists(Example<S> example);

    <S extends T> S save(S entity);

    <S extends T> List<S> save(Iterable<S> entities);

    <S extends T> S update(S entity);

    <S extends T> List<S> update(List<S> entity);

    void delete(ID id);


    void delete(T entity);
    EntityManager getEntityManager();


}